
#include <iostream>
#include <string.h>

#include "ttds_test.hpp"
#include "cutting_rect.hpp"


#define TTDS_MIN(a, b) ((a) < (b) ? (a) : (b))
#define TTDS_MAX(a, b) ((a) < (b) ? (b) : (a))


struct bmap
{
private:
    int x_max = 0;
    int y_max = 0;
    char b[200][200];

public:
    bmap() { clear(); }
    void clear(void)
    {
        memset(b, '.', sizeof(b));
        x_max = y_max = 0;
        for (int i = 0; i < 200; i++)
        {
            b[0][i + 1] = '0' + (i % 10);
        }
        for (int i = 0; i < 200; i++)
        {
            b[i + 1][0] = '0' + (i % 10);
        }
    }
    void set(int x, int y)
    {
        x++;
        y++;
        if (b[y][x] != '.')
        {
            b[y][x] = '#';
        }
        else
        {
            b[y][x] = '*';
        }
        x_max = TTDS_MAX(x_max, x);
        y_max = TTDS_MAX(y_max, y);
    }
    void show(void)
    {
        for (int y = y_max + 2; y >= 0; y--)
        {
            for (int x = 0; x <= x_max + 1; x++)
            {
                putchar(' ');
                putchar(b[y][x]);
            }
            putchar('\n');
        }
    }
};

void draw_to(bmap &bmp, int xoffset, ttds_rect &r)
{
    for (int i = 0; i < r.width; i++)
    {
        bmp.set(r.x + i + xoffset, r.y);
        bmp.set(r.x + i + xoffset, r.y + r.height - 1);
    }
    for (int i = 0; i < r.height; i++)
    {
        bmp.set(r.x + xoffset, r.y + i);
        bmp.set(r.x + r.width - 1 + xoffset, r.y + i);
    }
}

CTEST_BEGIN(rectA)

void print(void)
{
    bmap fb;
    ttds_rect a(1, 3, 9, 7);
    ttds_rect b(3, 1, 5, 10);
    ttds_rect r;
    ttds_rect_intersection(&a, &b, &r);
    draw_to(fb, 0, a);
    draw_to(fb, 0, b);
    draw_to(fb, 15, r);
    fb.show();
    CT_EQI(r.x, 3);
    CT_EQI(r.y, 3);
    CT_EQI(r.width, 5);
    CT_EQI(r.height, 7);
}

void test_offset(int ox, int oy)
{
    bmap fb;
    ttds_rect a(8, 8, 8, 8);
    ttds_rect b(3+ox, 1+oy, 5, 12);
    ttds_rect r;
    ttds_rect ra[4];
    ttds_rect rb[4];
    if (!ttds_rect_intersection(&a, &b, &r)){
        return ;
    }
    draw_to(fb, 0, a);
    draw_to(fb, 0, b);
    draw_to(fb, 15, r);
    ttds_rect_cut( &a, &b, ra, rb);
    for (int i=0; i<4; i++){
        printf("A:");
        if (ra[i].width){
            printf("#");
        } else {
            printf("-");
        }
        printf(" B:");
        if (rb[i].width){
            printf("#");
        } else {
            printf("-");
        }
        printf("\n");
        draw_to(fb, 30+i*8, ra[i] );
        draw_to(fb, 60+i*8, rb[i]);
    }
    fb.show();
}
void test8(void)
{
    printf("############################################################\n");
    for (int i=0; i<3000; i++){
        int ox = rand()%22;
        int oy = rand()%22;
        test_offset(ox, oy);
    }
    printf("############################################################\n");
}

void main()
{
    print();
    test8();
}

CTEST_END(rectA)
